package com.katesoft.scale4j.web.webconsole;

import java.security.Principal;
import java.util.Collection;

import org.mortbay.jetty.Request;
import org.mortbay.jetty.security.UserRealm;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;

import com.katesoft.scale4j.common.lang.RuntimeUtility;
import com.katesoft.scale4j.log.LogFactory;
import com.katesoft.scale4j.log.Logger;

/** @author kate2007 */
public class JettySpringSecurityUserRealm implements UserRealm {
   private final Logger logger = LogFactory.getLogger(getClass());
   private final AuthenticationManager authenticationManager;

   public JettySpringSecurityUserRealm(AuthenticationManager authenticationManager) {
      this.authenticationManager = authenticationManager;
   }

   @Override
   public String getName() {
      return "rttp.webconsole.user.realm" + System.getProperty(RuntimeUtility.VAR_SERVICE_ID);
   }

   @Override
   public Principal authenticate(String username, Object credentials,
            @SuppressWarnings("unused") Request r) {
      Authentication request = new UsernamePasswordAuthenticationToken(username,
               credentials.toString());
      try {
         Authentication response = authenticationManager.authenticate(request);
         String user = response.getPrincipal().toString();
         String password = response.getCredentials().toString();
         Collection<GrantedAuthority> authorities = response.getAuthorities();
         UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(user,
                  password, authorities);
         logger.debug("authenticated user=%s with credentials=%s", username, credentials);
         return token;
      } catch (AuthenticationException failed) {
         logger.debug("Authentication request for user[%s] failed: [%s] ", username,
                  failed.getMessage());
      }
      return null;
   }

   @Override
   public boolean reauthenticate(Principal user) {
      UsernamePasswordAuthenticationToken token = (UsernamePasswordAuthenticationToken) user;
      return token.isAuthenticated();
   }

   @Override
   public boolean isUserInRole(Principal user, String role) {
      boolean userInRole = false;
      UsernamePasswordAuthenticationToken token = (UsernamePasswordAuthenticationToken) user;
      Collection<GrantedAuthority> authorities = token.getAuthorities();
      for (GrantedAuthority authority : authorities) {
         if (authority.getAuthority().equals(role)) {
            userInRole = true;
         }
      }
      logger.debug("user=%s is in role=%s :=> %s", user.toString(), role, userInRole);
      return userInRole;
   }

   @SuppressWarnings("unused")
   @Override
   public void disassociate(Principal user) {
   }

   @SuppressWarnings("unused")
   @Override
   public Principal pushRole(Principal user, String role) {
      return user;
   }

   @Override
   public Principal popRole(Principal user) {
      return user;
   }

   @Override
   public void logout(Principal user) {
      logger.debug("onLogout(%s)", user);
   }

   @SuppressWarnings("unused")
   @Override
   public Principal getPrincipal(String username) {
      return null;
   }
}
